package com.woniu.gateway.filter;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.woniu.gateway.common.ResultBody;
import com.woniu.gateway.config.DataFilterConfig;
import com.woniu.gateway.util.JwtUtil;
import com.woniu.gateway.util.PathUtil;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;

/**
 * @Auther: 李浪  <br/>
 * @Date: 2020/3/26:0:34  <br/>
 * @Description:
 */
@Component
@Slf4j
public class LoginAddJwtPostFilter extends ZuulFilter {

    @Autowired
    ObjectMapper objectMapper;

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    DataFilterConfig dataFilterConfig;

    /**
     * pre：路由之前
     * routing：路由之时
     * post： 路由之后
     * error：发送错误调用
     *
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    /**
     * filterOrder：过滤的顺序
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 2;
    }

    /**
     * shouldFilter：这里可以写逻辑判断，是否要过滤
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        //路径与配置的相匹配，则执行过滤
        RequestContext ctx = RequestContext.getCurrentContext();
        for (String pathPattern : dataFilterConfig.getUserLoginPath()) {
            if (PathUtil.isPathMatch(pathPattern, ctx.getRequest().getRequestURI())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 执行过滤器逻辑，登录成功时给响应内容增加token
     *
     * @return
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
        //获取响应数据流 ，获取登录controller返回的结果
        InputStream inputStream = context.getResponseDataStream();
        try {
            //转换为字符串
            String result = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
            System.out.println(result);
            //将字符串转换为ResultBody
            ResultBody claims =  objectMapper.readValue(result,ResultBody.class);
            Date expireDate = DateTime.now().plusDays(3).toDate();
            //生成jwt令牌 ，并存储用户信息
            String token = jwtUtil.createJWT(expireDate,claims);
            context.setResponseStatusCode(HttpStatus.OK.value());
            //允许将token添加到响应头
            context.getResponse().addHeader("Access-Control-Expose-Headers","token");
            //将token字符串发送给前端,将token数据添加到响应头中
            context.getResponse().addHeader("token",token);
            //解决中文乱码问题
            context.getResponse().setContentType("text/html;charset=UTF-8");
            context.setResponseBody(claims.toString());
        }catch (Exception e){
            context.setResponseStatusCode(500);
            context.setResponseBody("{\"code\":500,\"message\":\"error\"}");
            e.printStackTrace();
        }
        return null;
    }
}

